#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "log.h"
#include "toolfun.h"
#include "haskelltool.h"
using namespace  HaskellTool;


void foldingFunction(std::vector<std::string> &resultList, std::string &str)
{
    int a ;
    int b ;
    int c;
    if (resultList.size() >= 2)
    {
        a = ToolFun::stringToNum<int>(resultList[0]);
        b = ToolFun::stringToNum<int>(resultList[1]);
    }
    if ("+" == str)
    {
        c = a + b;
    }
    else if ("-" == str)
    {
       c = b - a;
    }
    else if ("*" == str)
    {
       c = a * b;
    }
    else
    {
       resultList.insert(resultList.begin(), str);
       return;
    }

   resultList.erase(resultList.begin(), resultList.begin() + 2);
   resultList.insert(resultList.begin(), ToolFun::toString(c));
}

std::string solveRPN(std::string str)
{
    std::vector<std::string> resultList;
    return head( foldl(foldingFunction, resultList,  words(str) ));
}

/*

solveRPN1 ::  (Num a, Read a)=>String -> a
solveRPN1 = head . foldl foldingFunction [] . words
    where   foldingFunction (x:y:ys) "*" = (x * y):ys
            foldingFunction (x:y:ys) "+" = (x + y):ys
            foldingFunction (x:y:ys) "-" = (y - x):ys
            foldingFunction xs numberString = read numberString:xs
*/

std::string solveRPN2(std::string str)
{
    auto lambda1 = [](std::vector<std::string> &resultList, std::string &str)
    {
        int a ;
        int b ;
        int c;
        if (resultList.size() >= 2)
        {
            a = ToolFun::stringToNum<int>(resultList[0]);
            b = ToolFun::stringToNum<int>(resultList[1]);
        }
        if (str == "+")
        {
            c = a + b;
        }
        else if ("-" == str)
        {
           c = b - a;
        }
        else if ("*" == str)
        {
           c = a * b;
        }
        else
        {
           resultList.insert(resultList.begin(), str);
           return;
        }

       resultList.erase(resultList.begin(), resultList.begin() + 2);
       resultList.insert(resultList.begin(), ToolFun::toString(c));
    };
    /*
    std::vector<std::string > strList1 = words(str) ;
    foldl(foldingFunction, resultList,  strList1);
    foldl(lambda1, resultList,  strList1);
    foldl2(foldingFunction, resultList,  strList1);
    foldl2(lambda1, resultList,  strList1);
*/
    std::vector<std::string> resultList;
    return head(foldl(lambda1, resultList,  words(str)));

}
